import base64
import os.path
from datetime import time

import cv2
import numpy as np


class CvImageDistance:

    def from_file_get_distanct(self, tag_img_path, background_img_path):
        '''
        根据文件进行识别
        :param tag_img_path: 滑块图片的文件路径
        :param background_img_path: 背景图片的文件路径
        :return:
        '''
        target = cv2.imread(tag_img_path)
        # 读取到两个图片，进行灰值化处理
        template = cv2.imread(background_img_path, 0)
        # 转化到灰度
        target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
        # 返回绝对值
        target = abs(255 - target)
        # 单通道转3通道
        target = cv2.cvtColor(target, cv2.COLOR_GRAY2RGB)
        template = cv2.cvtColor(template, cv2.COLOR_GRAY2RGB)

        cv2.imwrite(filename="tag1.png", img=target)
        cv2.imwrite("background1.png", img=template)
        # 进行匹配
        result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
        # 通过np转化为数值，就是坐标
        x, y = np.unravel_index(result.argmax(), result.shape)
        return x

    def from_buffer_get_distanct(self, tag_img, background_img):
        '''
        根据二进制进行识别
        :param tag_img_path: 滑块图片的二进制
        :param bg: 背景图片的二进制
        :return:
        '''
        target = cv2.imdecode(np.frombuffer(tag_img, np.uint8), cv2.IMREAD_COLOR)

        # 如果是PIL.images就换读取方式
        template = cv2.imdecode(np.frombuffer(background_img, np.uint8), cv2.IMREAD_COLOR) if type(
            background_img) == bytes else cv2.cvtColor(
            np.asarray(background_img), cv2.COLOR_RGB2BGR)

        # 转化到灰度
        target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)

        # 返回绝对值
        target = abs(255 - target)

        # 单通道转3通道
        target = cv2.cvtColor(target, cv2.COLOR_GRAY2RGB)

        # 进行匹配
        result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)

        # 通过np转化为数值，就是坐标
        x, y = np.unravel_index(result.argmax(), result.shape)
        return y, x

    def get_distance(self, background_img_path, tag_img_path):

        # 读取到滑块图片的 rgb
        tag_rgb = cv2.imread(tag_img_path)

        # 添加边界，这里的-1代表通道数保持不变
        bordered_image = cv2.copyMakeBorder(tag_rgb, 10, 10, 10, 10, cv2.BORDER_CONSTANT, value=[0, 0, 0])

        # 转换到灰度
        gray_image = cv2.cvtColor(bordered_image, cv2.COLOR_BGR2GRAY)

        # 应用阈值化处理
        _, thresholded = cv2.threshold(gray_image, 1, 255, cv2.THRESH_BINARY)

        # 找到轮廓
        contours, _ = cv2.findContours(thresholded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

        # 找到边界框
        for contour in contours:
            x, y, w, h = cv2.boundingRect(contour)
            # 只保留面积较大的轮廓
            if cv2.contourArea(contour) > 100:
                # 裁剪图像
                cropped_image = bordered_image[y - 10:y + h + 10, x - 10:x + w + 10]

        lower_blue = np.array([96, 96, 96])  # 下界阈值
        upper_blue = np.array([255, 255, 255])  # 上界阈值

        tag_o = cv2.inRange(cropped_image, lowerb=lower_blue, upperb=upper_blue)

        # 读取到背景图片的 rgb
        background_rgb = cv2.imread(background_img_path)

        gray_b_image = cv2.cvtColor(background_rgb, cv2.COLOR_BGR2GRAY)

        cv2.imwrite('back2.png', gray_b_image)
        ret, thresh = cv2.threshold(gray_b_image, 127, 255, cv2.THRESH_TOZERO)
        cv2.imwrite('back1.png', thresh)
        cv2.imwrite('tag1.png', tag_o)

        # 计算结果
        res = cv2.matchTemplate(thresh, tag_o, cv2.TM_CCOEFF_NORMED)
        # 获取最小长度
        lo = cv2.minMaxLoc(res)

        # 识别返回滑动距离
        return lo[2][0]

    def get_diff_location(self, background_img_path, tag_img_path):
        # 获取图片并灰度化
        block = cv2.imread(tag_img_path, 0)
        template = cv2.imread(background_img_path, 0)
        # 二值化后的图片名称
        blockName = "block.jpg"
        templateName = "template.jpg"
        # 将二值化后的图片进行保存
        cv2.imwrite(blockName, block)
        cv2.imwrite(templateName, template)
        block = cv2.imread(blockName)
        block = cv2.cvtColor(block, cv2.COLOR_RGB2GRAY)
        block = abs(255 - block)
        cv2.imwrite(blockName, block)
        block = cv2.imread(blockName)
        template = cv2.imread(templateName)
        # 获取偏移量
        result = cv2.matchTemplate(block, template, cv2.TM_CCOEFF_NORMED)
        x, y = np.unravel_index(result.argmax(), result.shape)
        return y